﻿using System;
using System.Threading;
using System.Threading.Tasks;
using OpenSlideNET.Interop;

namespace WholeSlideImageLibrary.OpenSlide
{
    public class OpenSlideImageIdentifier : IImageIdentifier
    {
        public string Name => "OpenSlide";

        public int HeaderSize => 0;

        private static bool? s_isLibraryLoaded;

        private static bool LoadLibrary()
        {
            if (s_isLibraryLoaded.HasValue)
            {
                return s_isLibraryLoaded.GetValueOrDefault();
            }

            try
            {
                OpenSlideInterop.GetVersion();

                s_isLibraryLoaded = true;
            }
            catch (Exception)
            {
                s_isLibraryLoaded = false;
            }

            return s_isLibraryLoaded.GetValueOrDefault();
        }

        public ValueTask<ImageSourceType> IdentifyAsync(FileSourceInfo fileInfo, FileSourceReader reader, ReadOnlyMemory<byte> header, CancellationToken cancellationToken = default)
        {
            if (!(fileInfo is IPhysicalFileSource physicalFileSource))
            {
                return new ValueTask<ImageSourceType>(ImageSourceType.None);
            }
            if (!LoadLibrary())
            {
                return new ValueTask<ImageSourceType>(ImageSourceType.None);
            }
            return string.IsNullOrEmpty(OpenSlideInterop.DetectVendor(physicalFileSource.PhysicalFilePath)) ? new ValueTask<ImageSourceType>(ImageSourceType.None) : new ValueTask<ImageSourceType>(ImageSourceType.SingleImage);
        }

        public ValueTask<ImageSourceType> IdentifyAsync(DirectorySourceInfo directoryInfo, CancellationToken cancellationToken = default)
        {
            return new ValueTask<ImageSourceType>(ImageSourceType.None);
        }

        public ValueTask<WholeSlideImageCollection?> OpenImageCollectionAsync(FileSourceInfo fileInfo, FileSourceReader reader, CancellationToken cancellationToken = default)
        {
            throw new NotSupportedException();
        }

        public ValueTask<WholeSlideImageCollection?> OpenImageCollectionAsync(DirectorySourceInfo directoryInfo, CancellationToken cancellationToken = default)
        {
            throw new NotSupportedException();
        }

        public ValueTask<WholeSlideImage?> OpenSingleImageAsync(FileSourceInfo fileInfo, FileSourceReader reader, CancellationToken cancellationToken = default)
        {
            if (!(fileInfo is IPhysicalFileSource physicalFileSource))
            {
                return new ValueTask<WholeSlideImage?>((WholeSlideImage?)null);
            }
            if (!LoadLibrary())
            {
                return new ValueTask<WholeSlideImage?>((WholeSlideImage?)null);
            }
            return new ValueTask<WholeSlideImage?>(new OpenSlideWholeSlideImage(physicalFileSource.PhysicalFilePath));
        }

        public ValueTask<WholeSlideImage?> OpenSingleImageAsync(DirectorySourceInfo directoryInfo, CancellationToken cancellationToken = default)
        {
            throw new NotSupportedException();
        }
    }
}
